<?php

namespace app\controller;

use app\BaseController;
use app\common\Snowflake;
use think\facade\Db;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use app\validate\WebAdvertisementValidate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\facade\Request;
use think\exception\ValidateException;
use Exception;
use app\model\AdvertisementModel;

class WebAdvertisement extends BaseController
{
    // 新增广告图
    public function create()
    {
        $data = $this->request->post();
        validate(WebAdvertisementValidate::class)->check($data);

        $snowflake = new Snowflake(1, 1);
        $data['advertisement_id'] = $snowflake->nextId();

        $result = Db::name('advertisement')->insert($data);
        if ($result) {
            return json(['code' => 0, 'msg' => '新增成功', 'data' => ['advertisement_id' => $data['advertisement_id']]]);
        } else {
            return json(['code' => 1, 'msg' => '新增失败', 'data' => []]);
        }
    }

    // 编辑广告图
    public function update($id)
    {
        $data = $this->request->post();
        validate(WebAdvertisementValidate::class)->check($data);

        $result = Db::name('advertisement')->where('id', $id)->update($data);
        if ($result !== false) {
            return json(['code' => 0, 'msg' => '编辑成功', 'data' => []]);
        } else {
            return json(['code' => 1, 'msg' => '编辑失败', 'data' => []]);
        }
    }

    // 删除广告图
    public function delete($id)
    {
        $result = Db::name('advertisement')->where('id', $id)->delete();
        if ($result) {
            return json(['code' => 0, 'msg' => '删除成功', 'data' => []]);
        } else {
            return json(['code' => 1, 'msg' => '删除失败', 'data' => []]);
        }
    }

    // 广告图列表
    public function list()
    {
        // 获取并处理请求参数
        $params = [
            'advertisement_id' => $this->request->get('advertisement_id', ''),
            'id'               => $this->request->get('id', ''),
            'is_display'       => $this->request->get('is_display', -1), // 默认状态为全部
            'page'             => max(1, (int)$this->request->get('page', 1)),
            'limit'            => max(1, min(50, (int)$this->request->get('limit', 10)))
        ];

        // 构建查询条件
        $where = [];

        // 广告ID精确匹配
        if (!empty($params['advertisement_id'])) {
            $where[] = ['advertisement_id', '=', $params['advertisement_id']];
        }

        // id精确匹配
        if (!empty($params['id'])) {
            $where[] = ['id', '=', $params['id']];
        }

        // 显示状态处理
        if ($params['is_display'] != -1) {
            $where[] = ['is_display', '=', $params['is_display']];
        }

        // 查询总数
        $total = AdvertisementModel::where($where)->count();

        // 查询数据
        $list = AdvertisementModel::where($where)
            ->order('sort DESC, created_at DESC') // 增加排序字段
            ->page($params['page'], $params['limit'])
            ->select()
            ->toArray();

        // 数据格式化
        foreach ($list as &$item) {
            $item['is_display_text'] = $item['is_display'] == 1 ? '显示' : '隐藏';
            $item['jump_url'] = $item['jump_url'] ?? '无跳转地址';
        }

        return json([
            'code' => 0,
            'msg'  => '获取成功',
            'data' => [
                'list'  => $list,
                'total' => $total,
                'page'  => $params['page'],
                'limit' => $params['limit']
            ]
        ]);
    }

    // 导出广告图列表
    public function export()
    {
        // 获取并处理请求参数
        $params = [
            'advertisement_id' => $this->request->get('advertisement_id', ''),
            'id'               => $this->request->get('id', ''),
            'is_display'       => $this->request->get('is_display', -1),
        ];

        // 构建查询条件
        $where = [];

        // 广告ID精确匹配
        if (!empty($params['advertisement_id'])) {
            $where[] = ['advertisement_id', '=', $params['advertisement_id']];
        }

        // id精确匹配
        if (!empty($params['id'])) {
            $where[] = ['id', '=', $params['id']];
        }

        // 显示状态处理
        if ($params['is_display'] != -1) {
            $where[] = ['is_display', '=', $params['is_display']];
        }

        $query = AdvertisementModel::where($where);

        $list = $query->order('sort DESC, created_at DESC')->select()->toArray();

        foreach ($list as &$item) {
            $item['is_jump'] = $item['click_type'] == 0 ? '是' : '否';
            $item['is_display_text'] = $item['is_display'] == 1 ? '是' : '否';
        }

        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setCellValue('A1', '广告图ID');
        $sheet->setCellValue('B1', '图片URL地址');
        $sheet->setCellValue('C1', '是否跳转');
        $sheet->setCellValue('D1', '显示');
        $sheet->setCellValue('E1', '排序');
        $sheet->setCellValue('F1', '修改时间');

        $row = 2;
        foreach ($list as $item) {
            $sheet->setCellValue('A' . $row, $item['advertisement_id']);
            $sheet->setCellValue('B' . $row, $item['image_url']);
            $sheet->setCellValue('C' . $row, $item['is_jump']);
            $sheet->setCellValue('D' . $row, $item['is_display_text']);
            $sheet->setCellValue('E' . $row, $item['sort']);
            $sheet->setCellValue('F' . $row, $item['updated_at']);
            $row++;
        }

        $format = $this->request->get('format', 'csv');
        $fileName = date('Ymd') . '_导出的广告图列表.' . ($format == 'xls' ? 'xlsx' : 'csv');
        if ($format == 'xls') {
            $writer = new Xlsx($spreadsheet);
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        } else {
            $writer = new Csv($spreadsheet);
            header('Content-Type: text/csv');
        }
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Cache-Control: max-age=0');
        $writer->save('php://output');
    }

    public function import()
    {
        // 获取上传文件
        $file = Request::file('file');
        if (!$file) {
            return json(['code' => 1, 'msg' => '请选择要上传的文件', 'data' => []]);
        }

        // 验证文件格式
        $allowExt = ['csv', 'xlsx', 'xls'];
        $ext = $file->getOriginalExtension();
        if (!in_array($ext, $allowExt)) {
            return json(['code' => 1, 'msg' => '仅支持CSV/Excel文件', 'data' => []]);
        }

        // 移动文件到临时目录
        $savePath = runtime_path() . 'import/';
        if (!is_dir($savePath)) {
            mkdir($savePath, 0755, true);
        }
        $filename = uniqid() . '.' . $ext;
        $file->move($savePath, $filename);
        $filePath = $savePath . $filename;

        try {
            // 读取文件内容
            $spreadsheet = IOFactory::load($filePath);
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray();

            // 全局替换null为空字符串
            $rows = array_map(function ($row) {
                return array_map(fn ($v) => $v === null ? '' : $v, $row);
            }, $rows);

            $success = 0;
            $errors = [];
            $snowflake = new Snowflake(1, 1);

            // 校验表头（中英文对照）
            $header = array_map('trim', $rows[0]);
            $requiredHeaders = ['广告ID', '标题', '图片URL', '点击类型', '跳转地址', '排序', '是否展示', '产品唯一标识ID'];
            foreach ($requiredHeaders as $h) {
                if (!in_array($h, $header)) {
                    throw new \Exception("缺少必要表头：{$h}");
                }
            }

            // 从第二行开始处理
            for ($rowNum = 1; $rowNum < count($rows); $rowNum++) {
                $row = $rows[$rowNum];
                if (empty(array_filter($row))) {
                    $errors[] = ['row' => $rowNum + 1, 'msg' => '数据为空行'];
                    continue;
                }

                // 按列顺序解析数据
                $data = [
                    'advertisement_id' => $row[0] ?? '',
                    'title'            => $row[1] ?? '',
                    'image_url'        => $row[2] ?? '',
                    'click_type'       => $row[3] ?? '',
                    'jump_url'         => $row[4] ?? '',
                    'sort'             => $row[5] ?? 0,
                    'is_display'       => $row[6] ?? 0,
                    'app_id'           => $row[7] ?? ''
                ];

                // === 数据转换 ===
                // 1. 生成广告ID
                if (empty($data['advertisement_id'])) {
                    $data['advertisement_id'] = $snowflake->nextId();
                }

                // 2. 点击类型转换
                $data['click_type'] = match ($data['click_type']) {
                    '跳转', '1' => 1,
                    '下载', '2' => 2,
                    default => throw new \Exception("第" . ($rowNum + 1) . "行点击类型值无效")
                };

                // 3. 是否展示转换
                $data['is_display'] = match ($data['is_display']) {
                    '展示', '1' => 1,
                    '不展示', '0' => 0,
                    default => 0
                };

                // 4. 排序处理
                $data['sort'] = intval($data['sort']);

                // === 数据验证 ===
                $validate = new \think\Validate([
                    'title'       => 'require|max:255',
                    'image_url'   => 'require|url',
                    'click_type'  => 'require|in:1,2',
                    'jump_url'    => 'url',
                    'sort'        => 'integer',
                    'is_display'  => 'in:0,1',
                    'app_id'      => 'require|max:32'
                ]);

                // 动态添加跳转地址必填规则
                if ($data['click_type'] == 1) {
                    $validate->append('jump_url', 'require');
                }

                if (!$validate->check($data)) {
                    $errors[] = [
                        'row' => $rowNum + 1,
                        'msg' => $validate->getError()
                    ];
                    continue;
                }

                // === 唯一性校验 ===
                if (Db::name('advertisement')->where('advertisement_id', $data['advertisement_id'])->find()) {
                    $errors[] = [
                        'row' => $rowNum + 1,
                        'msg' => "广告ID已存在：{$data['advertisement_id']}"
                    ];
                    continue;
                }

                // === 写入数据库 ===
                try {
                    Db::name('advertisement')->insert($data);
                    $success++;
                } catch (\Exception $e) {
                    $errors[] = [
                        'row' => $rowNum + 1,
                        'msg' => "数据库错误：{$e->getMessage()}"
                    ];
                }
            }

            // 删除临时文件
            @unlink($filePath);

            return json([
                'code' => 0,
                'msg'  => "导入完成，成功{$success}条，失败" . count($errors) . "条",
                'data' => [
                    'success' => $success,
                    'errors'  => $errors
                ]
            ]);

        } catch (\Exception $e) {
            @unlink($filePath);
            return json([
                'code' => 1,
                'msg'  => "导入失败：{$e->getMessage()}",
                'data' => []
            ]);
        }
    }
}